module key_filter(
	clk,
	rst_n,
	key,
	key_flag,
	key_state
);

	input clk;
	input rst_n;
	input key;
	output key_flag;
	output key_state;
	

	reg key_tmpa,key_tmpb;
		
	wire pedge_key;
	wire nedge_key;
	
//边沿检测	
	always@(posedge clk or negedge rst_n)
	if(!rst_n)begin
		key_tmpa <= 1'b0;
		key_tmpb <= 1'b0;
	end
	else begin
		key_tmpa <= key;
		key_tmpb <= key_tmpa;
	end

	assign pedge_key = ((!key_tmpb) && key_tmpa);
	assign nedge_key = ((!key_tmpa) && key_tmpb);
	

//计数使能模块	
	reg [19:0]cnt;
	reg cnt_full;
	reg en_cnt; //使能计数器

	always@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt <= 20'd0;
	else if(en_cnt)
		cnt <= cnt + 1'b1;
	else
		cnt <= 20'd0;
//计数模块
	always@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt_full <= 1'b0;	
	else if(cnt == 20'd999_999)
		cnt_full <= 1'b1;
	else
		cnt_full <= 1'b0;
		
//状态机模块
	localparam 
		IDLE = 4'b0001,
		FILTER0 = 4'b0010,
		DOWN = 4'b0100,
		FILTER1 = 4'b1000;
	reg [3:0]state;	
	reg key_flag;
	reg key_state;
	
	always@(posedge clk or negedge rst_n)
	if(!rst_n)begin
		en_cnt <= 0;
		state <= IDLE;
		key_flag <= 1'b0;
		key_state <= 1'b1;
	end
	else begin
		case(state)
			IDLE:
				begin
					key_flag <= 1'b0;
					if(nedge_key) begin
						state <= FILTER0;
						en_cnt <= 1'b1;
					end
					else
						state <= IDLE;
				end
			
			FILTER0:
				if(cnt_full)begin
					key_flag <= 1'b1;
					key_state <= 1'b0;
					state <= DOWN;
					en_cnt <= 1'b0;
				end
				else if(pedge_key)begin
					en_cnt <= 1'b0;
					state <= IDLE;
				end
				else
					state <= FILTER0;

			DOWN:
				begin
					key_flag <= 1'b0;
					if(pedge_key)begin
						state <= FILTER1;
						en_cnt <= 1'b1;
					end
					else
						state <= DOWN;
				end
					
			FILTER1:
				if(cnt_full)begin
					key_flag <= 1'b1;
					key_state <= 1'b1;
					state <= IDLE;
					en_cnt <= 1'b0;
				end
				else if(nedge_key)begin
					en_cnt <= 1'b0;
					state <= DOWN;
				end
				else
					state <= FILTER1;
			default:
				begin
					state <= IDLE;
					en_cnt <= 1'b0;
					key_flag <= 1'b0;
					key_state <= 1'b1;
				end		
		endcase
		
	end
endmodule 